﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using API;
using AVFoundation;
using AVKit;
using CoreFoundation;
using CoreGraphics;
using Foundation;
using mb;
using mb.iOS;
using Masonry;
using MyExtensions;
using UIKit;
using static libmp.DataStore;
using System.Collections.Generic;
using System.Net.Http;

namespace libmp
{

    class VCMoviePlayer : VCExMovieList
    {
        AVPlayerViewController avController = new AVPlayerViewController();
        AVPlayer player;
        MyResourceLoader myLoader;
        IDisposable obStatus;
        IDisposable obError;
        VideoItem movieInfo;
        UIView topBarView;
        MyVideoView movieView;
        UIView desc1View;
        UIView desc2View;
        UIView desc3View;
        UILabel viewInfoTitle;
        UILabel[] viewInfoLabels;
        int HeaderHeight = 0;

        List<InsertItem> insertViewInfos;
        UIPlaybackControllView pbcView;
        UIButton btnBack;
        UIActivityIndicatorView loadingView;

        public VCMoviePlayer(VideoItem item) : base()
        {
            movieInfo = item;
        }

        public override void ViewDidLoad()
        {
            // if (!checkIfCanView(movieInfo.vid)) { return; }

            //在base之前创建背景，否则把list挡了
            var bkView = new UIView() { BackgroundColor = Util.MainBKColor };
            bkView.SetParent(View).MakeConstraints(m =>
            {
                m.Top.EqualTo(this.TopLayoutGuideBottom());
                m.Left.Right.Bottom.EqualTo(View);
            });

            base.ViewDidLoad();

            dataSource = DataStore.store.GetRecommendVideo(movieInfo.vcateid, movieInfo.vid);

            CreateMovieView();
            createDesc1View();
            createDesc2View();
            createDesc3View();

            insertViewInfos = new List<InsertItem>();
            insertViewInfos.Add(new InsertItem() { view = movieView, insertBefore = 0, height = 400, stickyHeight = 150 });
            insertViewInfos.Add(new InsertItem() { view = desc1View, insertBefore = 0, height = 40, stickyHeight = 40 });
            insertViewInfos.Add(new InsertItem() { view = desc2View, insertBefore = 0, height = 40, stickyHeight = 40 });
            insertViewInfos.Add(new InsertItem() { view = desc3View, insertBefore = 0, height = 60, stickyHeight = 0 });

            //以下代码不要删，当调试布局bug时需要它们显眼
            // new UILabel() { Text = "top" }.SetParent(movieView).MakeConstraints(m => m.CenterY.EqualTo(movieView));
            // desc1View.BackgroundColor = UIColor.Yellow;
            // desc2View.BackgroundColor = UIColor.Red;
            // desc3View.BackgroundColor = UIColor.Green;

            listView.RefreshControl = new UIRefreshControl();
            listView.RefreshControl.ValueChanged += async(s, e) =>
            {
                logger.Log("changed");
                await Task.Delay(1500);
                listView.RefreshControl.EndRefreshing();
            };
            listView.RemakeConstraints(m =>
            {
                m.Left.Right.EqualTo(View);
                m.Top.EqualTo(this.TopLayoutGuideBottom()).Offset(HeaderHeight);
                m.Bottom.EqualTo(this.BottomLayoutGuideTop());
            });

            this.Reload();

            ReloadMovie();
        }

        void CreateMovieView()
        {
            movieView = new MyVideoView() { BackgroundColor = UIColor.Black.ColorWithAlpha(0.99f) };

            loadingView = new UIActivityIndicatorView();
            loadingView.SetParent(movieView);
            loadingView.MakeConstraints(m =>
            {
                m.Center.EqualTo(movieView);
            });

            pbcView = new UIPlaybackControllView();
            pbcView.RootView = View;
            pbcView.SetParent(movieView);
            pbcView.MakeConstraints(m =>
            {
                m.Bottom.EqualTo(movieView);
                m.Left.EqualTo(movieView).Offset(20);
                m.Right.EqualTo(movieView).Offset(-20);
            });
            btnBack = new UIButton();
            btnBack.SetParent(movieView);
            btnBack.SetImage(Util.UIImageFromHotFile("user/Fanhui.png").ToRetina(1).WithColor(Util.MainColor), UIControlState.Normal);
            btnBack.MakeConstraints(m =>
            {
                //iphoneX以上底边有圆角，太靠边了不好点，因此使用safearealayout让它偏一点
                if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
                {
                    m.Left.EqualTo(movieView.SafeAreaLayoutGuideLeft()).Offset(10);
                    m.Top.EqualTo(movieView.SafeAreaLayoutGuideTop()).Offset(10);
                }
                else
                {
                    m.Left.Top.EqualTo(movieView).Offset(10);
                }
            });
            btnBack.TouchUpInside += (s, e) =>
            {
                var isLandscape = UIDevice.CurrentDevice.Orientation.IsLandscape();
                logger.Log("click back", isLandscape);
                if (isLandscape)
                {
                    UIDevice.CurrentDevice.SetValueForKey(NSObject.FromObject((int) UIInterfaceOrientation.Portrait), new NSString("orientation"));
                    return;
                }
                AppDelegate.Instance.NavController.PopViewController(false);
            };
        }
        private void createDesc1View()
        {
            desc1View = new UIView() { BackgroundColor = UIColor.White };
            var descImageViewButton = new UIImageView();
            var imgoperationArrow = UIImage.FromFile($"{App.HotStorageRoot}/res/adverise/YaoqingHaoyou.png");
            descImageViewButton.Image = new UIImage(imgoperationArrow.CGImage, 2, UIImageOrientation.Up);
            descImageViewButton.SetParent(desc1View);
            descImageViewButton.MakeConstraints(m =>
            {
                m.Top.EqualTo(NSObject.FromObject(8));
                m.Left.EqualTo(NSObject.FromObject((View.Bounds.Width - 250) / 2));
                m.Height.EqualTo(NSObject.FromObject(30));
                m.Width.EqualTo(NSObject.FromObject(250));
            });
        }

        private void createDesc2View()
        {
            desc2View = new UIView() { BackgroundColor = UIColor.White };
            viewInfoTitle = new UILabel();
            viewInfoTitle.SetParent(desc2View);
            viewInfoTitle.Frame = new CGRect(10, 0, View.Bounds.Width - 50, 40);
            viewInfoTitle.TextAlignment = UITextAlignment.Left;
            viewInfoTitle.Text = movieInfo.vname;
            viewInfoTitle.Font = UIFont.SystemFontOfSize(13);
            viewInfoTitle.TextColor = UIColor.FromRGB(93, 93, 93);

            var downImageViewButton = new UIImageView();
            var imgoperationArrow = UIImage.FromFile($"{App.HotStorageRoot}/res/category/Down.png");
            downImageViewButton.Image = new UIImage(imgoperationArrow.CGImage, 2, UIImageOrientation.Up);
            downImageViewButton.SetParent(desc2View);
            downImageViewButton.MakeConstraints(m =>
            {
                m.Top.EqualTo(NSObject.FromObject(16));
                m.Left.EqualTo(NSObject.FromObject(View.Bounds.Width - 40));
                m.Height.EqualTo(NSObject.FromObject(8));
                m.Width.EqualTo(NSObject.FromObject(16));
            });
        }

        private void createDesc3View()
        {
            desc3View = new UIView() { BackgroundColor = UIColor.White };
            var desc3ViewTop = new UIView();
            desc3ViewTop.SetParent(desc3View);
            desc3ViewTop.Frame = new CGRect(0, 0, View.Bounds.Width, 60);
            desc3ViewTop.BackgroundColor = UIColor.FromRGB(248, 248, 248);
            var picItems = new string[]
            {
                "Dianzan.png",
                "Zhiboguankan.png",
                "Shoucang.png",
                "Zhuanfa.png"
            };
            viewInfoLabels = new UILabel[]
            {
                new UILabel(), new UILabel(), new UILabel(), new UILabel()
            };
            var itemWidth = View.Bounds.Width / 4;
            for (int i = 0; i < picItems.Length; i++)
            {
                var oneItemView = new UIView();
                oneItemView.SetParent(desc3ViewTop);
                oneItemView.Frame = new CGRect(i * itemWidth, 0, itemWidth, 60);
                var oneItemImageView = new UIImageView();
                var imgoperationArrow = UIImage.FromFile($"{App.HotStorageRoot}/res/category/{picItems[i]}");
                oneItemImageView.Image = new UIImage(imgoperationArrow.CGImage, 2, UIImageOrientation.Up);
                oneItemImageView.SetParent(oneItemView);
                oneItemImageView.MakeConstraints(m =>
                {
                    m.CenterX.EqualTo(oneItemView.CenterX());
                    m.Top.EqualTo(NSObject.FromObject(5));
                    m.Height.EqualTo(NSObject.FromObject(30));
                    m.Width.EqualTo(NSObject.FromObject(30));
                });

                viewInfoLabels[i].SetParent(desc3ViewTop);
                viewInfoLabels[i].Frame = new CGRect(i * itemWidth, 35, itemWidth, 20);
                viewInfoLabels[i].TextAlignment = UITextAlignment.Center;
                viewInfoLabels[i].Font = UIFont.SystemFontOfSize(12);
                viewInfoLabels[i].TextColor = UIColor.FromRGB(93, 93, 93);
            }
            viewInfoLabels[0].Text = movieInfo.praises + "";
            viewInfoLabels[1].Text = movieInfo.views + "";
            viewInfoLabels[2].Text = movieInfo.favs + "";
            viewInfoLabels[3].Text = movieInfo.forwords + "";

            // var desc3ViewBottom = new UIView();
            // desc3ViewBottom.SetParent(desc3View);
            // desc3ViewBottom.Frame = new CGRect(0, 60, View.Bounds.Width, 40);
            // desc3ViewBottom.BackgroundColor = UIColor.FromRGB(235, 235, 235);
        }

        public override void ViewDidDisappear(bool animated)
        {
            StopPlayer();
            AppDelegate.Instance.NavController.EnableRotation = false;
        }
        public override void ViewDidAppear(bool animated)
        {
            AppDelegate.Instance.NavController.EnableRotation = true;
        }

        public override void ViewWillTransitionToSize(CGSize toSize, IUIViewControllerTransitionCoordinator coordinator)
        {
            base.ViewWillTransitionToSize(toSize, coordinator);
            logger.Log("ViewWillTransitionToSize", toSize, UIDevice.CurrentDevice.Orientation);
            if (UIDevice.CurrentDevice.Orientation.IsLandscape())
            {
                logger.Log("landscape");
                gotoFullScreen(true);
            }
            else
            {
                logger.Log("portrait");
                gotoFullScreen(false);

            }
        }

        UIView lastParent;
        CGRect lastFrame;
        async void gotoFullScreen(bool b)
        {
            if (b)
            {
                lastFrame = movieView.Frame;
                lastParent = movieView.Superview;

                var size = UIScreen.MainScreen.Bounds;
                var bh = this.BottomLayoutGuide.Length;
                var th = this.TopLayoutGuide.Length;
                logger.Log("enter fullscreen", lastFrame, bh, th);
                movieView.RemoveFromSuperview();
                movieView.SetParent(View);
                movieView.Frame = new CGRect(0, 0, size.Height, size.Width);
                UIApplication.SharedApplication.SetStatusBarHidden(true, false);
            }
            else
            {
                logger.Log("exit fullscreen", lastFrame);
                movieView.RemoveFromSuperview();
                movieView.SetParent(lastParent);
                movieView.Frame = lastFrame;
                UIApplication.SharedApplication.SetStatusBarHidden(false, true);
                // listView.ScrollToItem(NSIndexPath.FromItemSection(0, 0), UICollectionViewScrollPosition.Bottom, false);
                // listView.ScrollToItem(NSIndexPath.FromItemSection(0, 0), UICollectionViewScrollPosition.Top, true);
                await Task.Delay(10);
                UpdateSticky();

            }
        }

        protected override int[] GetInsertIndex() => insertViewInfos.Select(v => v.insertBefore).ToArray();
        protected override InsertItem GetInsertViewConfig(int idx)
        {
            // logger.Log("GetInsertViewConfig--------------->" + idx);
            return new InsertItem()
            {
                overwrite = (idx == 1 || idx == 3),
                    height = insertViewInfos[idx].height,
                    stickyHeight = insertViewInfos[idx].stickyHeight,
                    view = insertViewInfos[idx].view,
            };
        }
        protected override UIView GetInsertView(int idx, MyCollectionViewCell cell)
        {
            // logger.Log("GetInsertView--------------->" + idx);
            var view = insertViewInfos[idx].view;
            view.Frame = CGRect.FromLTRB(0, 0, cell.Frame.Width, cell.Frame.Height);
            return view;
        }
        async void CreateAVPlayer()
        {
            reloadStartTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            bool useCustomLoader = true;
            useCustomLoader = false;
            if (useCustomLoader)
            {
                var url = mb.iOS.Util.EncodeStringToUrl($"{movieInfo.vpath}".Replace("http", MyResourceLoaderDS.SchemaHolder));
                var asset = AVAsset.FromUrl(url) as AVUrlAsset;
                myLoader = new MyResourceLoaderDS(asset, movieInfo.vkey);
                player = AVPlayer.FromPlayerItem(AVPlayerItem.FromAsset(asset));
            }
            else
            {
                var url = GlobalImpl.VideoServer.GetVideoUrl(movieInfo.vid);
                var asset = AVAsset.FromUrl(new NSUrl(url)) as AVUrlAsset;
                player = AVPlayer.FromPlayerItem(AVPlayerItem.FromAsset(asset));
            }

            //先重置到一个默认值
            var ins = insertViewInfos[0];
            ins.height = ins.stickyHeight = 400;
            listView.ScrollToItem(NSIndexPath.FromItemSection(0, 0), UICollectionViewScrollPosition.Top, false);
            await Task.Delay(10); //调用scroll后cell状态没有马上更新，只能等下一帧它算完了再去更新stickyitem状态
            UpdateSticky();
            loadingView.StartAnimating();
            (movieView.Layer as AVPlayerLayer).Player = null;
            pbcView.Hidden = true;

            obError = player.AddObserver("error", Foundation.NSKeyValueObservingOptions.Initial | Foundation.NSKeyValueObservingOptions.OldNew, async o =>
            {
                logger.Log("observe error", o, player.Error);
            });

            //等待视频准备好后，再根据宽高比调整视频区域大小
            obStatus = player.AddObserver("status", Foundation.NSKeyValueObservingOptions.Initial | Foundation.NSKeyValueObservingOptions.OldNew, async o =>
            {
                reloadReadyTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                logger.Log("observe status", o, player.Status);
                if ((int) player.Status != (int) AVPlayerStatus.ReadyToPlay) return;
                var tracks = player.CurrentItem.Asset.TracksWithMediaType(AVMediaType.Video);
                if (tracks.Length == 0) return;
                var tr = tracks.First();
                logger.Log("track", tr.NaturalSize, tr.PreferredTransform);

                double aspectRatio = (double) tr.NaturalSize.Height / tr.NaturalSize.Width;
                var frame = listView.Frame;
                if (aspectRatio > 1)
                {
                    int height = (int) (frame.Width * aspectRatio);
                    height = Math.Min(height, (int) (frame.Height * 0.8));
                    ins.height = height;
                    ins.stickyHeight = height / 2;
                }
                else
                {
                    ins.height = ins.stickyHeight = (int) (frame.Width * aspectRatio);
                }
                Reload();
                await Task.Delay(10);
                UpdateSticky();
                loadingView.StopAnimating();
                pbcView.Hidden = false;

                (movieView.Layer as AVPlayerLayer).Player = player;
                player.Play();
                pbcView.avPlayer = player;
            });

        }

        protected override void OnItemSelected(int sec, int idx)
        {
            if (sec == 1)
            {
                logger.Log("点击广告按钮了");
            }
            if (sec == 2)
            {
                logger.Log("点击标题");
            }
            if (sec > 3)
            {
                var sd = sections[sec];
                StopPlayer();
                movieInfo = dataSource[sd.dataStartIndex + idx];
                ReloadMovie();
            }
        }

        void ReloadMovie()
        {
            viewInfoTitle.Text = movieInfo.vname;
            viewInfoLabels[0].Text = movieInfo.praises + "";
            viewInfoLabels[1].Text = movieInfo.views + "";
            viewInfoLabels[2].Text = movieInfo.favs + "";
            viewInfoLabels[3].Text = movieInfo.forwords + "";
            CreateAVPlayer();
        }

        void StopPlayer()
        {
            player?.Pause();
            myLoader?.Close();
            obStatus?.Dispose();
            obError?.Dispose();
            GlobalImpl.VideoServer.CloseCurrentStream();
            pbcView?.Stop();

            if (reloadStartTime > 0)
            {
                long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                User.me.Notify("views", LitJson.JsonMapper.ToJson(new
                {
                    movieId = movieInfo.vid,
                        movieName = movieInfo.vname,
                        viewTime = reloadStartTime,
                        loadTime = reloadReadyTime,
                        viewDuration = (now - reloadStartTime) / 1000,
                }));
            }
        }

        long reloadStartTime;
        long reloadReadyTime;

        //以下为观看次数设定
        // bool checkIfCanView(int vid)
        // {
        //     logger.Log("当前观看次数:----------->" + User.me.viewsNums);
        //     bool ok = false;
        //     if (checkViewIdIfNew(vid) && !checkUserIfMember())
        //     {
        //         if (User.me.viewsNums > 0)
        //         {
        //             User.me.viewsNums--;
        //             User.me.Save();
        //             //此处通讯服务器更改剩余观看次数
        //             Util.UpdateViewNums(User.me.id, User.me.viewsNums, false);
        //             ok = true;
        //         }
        //     }
        //     else
        //     {
        //         ok = true;
        //     }
        //     if (!ok)
        //     {
        //         var width = (float) (View.Bounds.Width * 0.8);
        //         var height = (float) (View.Bounds.Height * 0.5);
        //         var popView = Util.createPopView(width, height);
        //         MyPopupManager.ShowPopView(popView, width, height);
        //         AppDelegate.Instance.NavController.PopViewController(false);
        //         return false;
        //     }
        //     else
        //     {
        //         User.me.addViewId(vid);
        //         return true;
        //     }

        // }

        // bool checkViewIdIfNew(int vid)
        // {
        //     //return false;
        //     //检测影片ID当日是否已经看过 
        //     logger.Log("vid------", vid, "User.me.checkViewId(vid)----", User.me.checkViewId(vid));
        //     var res = User.me.checkViewId(vid);
        //     return !res;
        // }

        // bool checkUserIfMember()
        // {
        //     var dueDate = User.me.dueDate;
        //     if (dueDate.Length > 0)
        //     {
        //         DateTime dt = DateTime.Now;
        //         var nowTime = dt.ToString("yyyy-MM-dd");
        //         DateTime dt1 = Convert.ToDateTime(dueDate);
        //         DateTime dt2 = Convert.ToDateTime(nowTime);
        //         int compNum = DateTime.Compare(dt1, dt2);
        //         if (compNum >= 0)
        //         {
        //             return true;
        //         }
        //     }
        //     return false;
        // }

    }
}